﻿// codeing/urlcode.cpp
//用于url相关编码和解码
#include "pch.h"

//CXTextA WEBOAT_API WoCodingUrlEncodeA(const char* str) {
//    CXTextA new_str = "";
//    char c;
//    int ic;
//    const char* chars = str;
//    char bufHex[10];
//    int len = strlen(chars);
//
//    for (int i = 0; i < len; i++) {
//        c = chars[i];
//        ic = c;
//        // uncomment this if you want to encode spaces with +
//        /*if (c==' ') new_str += '+';
//        else */if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') new_str += c;
//        else {
//            sprintf_s(bufHex, "%X", c);
//            if (ic < 16)
//                new_str += "%0";
//            else
//                new_str += "%";
//            new_str += bufHex;
//        }
//    }
//    return new_str;
//}
//
//CXTextA WEBOAT_API WoCodingUrlDecodeA(const char* str) {
//    CXTextA l = str;
//    CXTextA ret;
//    char ch;
//    int i, ii, len = strlen(str);
//
//    for (i = 0; i < len; i++) {
//        if (str[i] != '%') {
//            if (str[i] == '+')
//                ret += ' ';
//            else
//                ret += str[i];
//        }
//        else {
//            sscanf_s(l.substr(i + 1, 2).get(), "%x", &ii);
//            ch = static_cast<char>(ii);
//            ret += ch;
//            i = i + 2;
//        }
//    }
//    return ret;
//}



inline static const char _WOURLDECOD_X[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0,
  0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
CXTextA WEBOAT_API WoCodingUrlDecodeA(const char* d) {
	std::string s(d); char* o = (char*)s.data(), * c = (char*)s.data();
	const char* e = c + s.length(); while (c < e) {
		if (*c == '%' && c < e - 2) {
			*o = (_WOURLDECOD_X[c[1]] << 4) | _WOURLDECOD_X[c[2]]; c += 2;
		}
		else if (*c == '+') {
			*o = ' ';
		}
		else if (o != c) *o = *c; ++o; ++c;
	} return std::string(s.c_str(), o - s.c_str());
}

inline static char _WOURLDECOD_HEX_[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0x2b, 0x21, 0, 0x23, 0x24, 0, 0x26, 0x27, 0x28, 0x29, 0x2a, 0, 0x2c, 0x2d , 0x2e, 0x2f,
0x30 , 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0, 0x3d, 0, 0x3f, 0x40, 0x41,
0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0, 0x5d, 0, 0x5f, 0, 0x61, 0x62, 0x63, 0x64,
0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0x7e, 0 };//RFC3986

CXTextA WEBOAT_API WoCodingUrlEncodeA(const char* c) {
	std::string r; while (*c) {
		if (*c > '\377') {
			if (_WOURLDECOD_HEX_[*c])r.push_back(_WOURLDECOD_HEX_[*c]);
			else {
				r.push_back(0x25); char o = (*c & 0xF0) >> 4;
				o += o > 9 ? 0x37 : 0x30; r.push_back(o);
				o = *c & 0x0F; o += o > 9 ? 0x37 : 0x30; r.push_back(o);
			}
		}
		else {
			r.push_back(0x25);
			char o = (static_cast<uint8_t>(*c) & 0xF0) >> 4;
			o += o > 9 ? 0x37 : 0x30; r.push_back(o);
			o = static_cast<uint8_t>(*c) & 0x0F;
			o += o > 9 ? 0x37 : 0x30; r.push_back(o);
		} ++c;
	} return r;
}

